package cn.net.sinodata.system.runner;

import cn.net.sinodata.common.core.constant.CacheNames;
import cn.net.sinodata.common.hazelcast.utils.HazelcastUtils;
import cn.net.sinodata.system.domain.PmUniqueElement;
import cn.net.sinodata.system.domain.SysDictData;
import cn.net.sinodata.system.mapper.*;
import cn.net.sinodata.system.msghandler.parse.scripthandler.ScriptLoader;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 项目缓存加载器
 * @author yinliangyun
 */
@Slf4j
@RequiredArgsConstructor
@Component
public class CacheApplicationRunner implements ApplicationRunner {

    @Value("${script.groovy.path}")
    private String scriptPath;

    @Autowired
    private SysConfigMapper sysConfigMapper;
    @Autowired
    private SysDictTypeMapper sysDictTypeMapper;
    @Autowired
    private SysDictDataMapper sysDictDataMapper;
    @Autowired
    private PmTransChannelMapper pmTransChannelMapper;
    @Autowired
    private PmMsgTemplateMapper pmMsgTemplateMapper;
    @Autowired
    private PmUniqueValidationMapper pmUniqueValidationMapper;
    @Autowired
    private PmUniqueElementMapper pmUniqueElementMapper;
    @Autowired
    private ScriptLoader scriptLoader;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        log.info("CacheApplicationRunner run start");
        initializeCache();
        loadScript();
        log.info("CacheApplicationRunner run end");
    }

    /**
     * 系统脚本加载到缓存中
     */
    private void loadScript() throws Exception {
        log.info("加载脚本文件-开始");
        scriptLoader.preloader(scriptPath);
        log.info("加载脚本文件-结束");
    }

    /**
     * 整体加载缓存
     */
    public void initializeCache() {
        initializeSysConfigCache();
        initializeSysDictCache();
        initializePmTransChannelCache();
        initializePmMsgTemplate();
        initializePmUniqueValidation();
    }

    /**
     * 初始化交易渠道
     */
    public void initializePmTransChannelCache() {
        pmTransChannelMapper.selectList().forEach(sysTransChannel ->
            HazelcastUtils.addCache(CacheNames.PM_TRANS_CHANNEL, sysTransChannel.getTransChannelCode(), sysTransChannel)
        );
    }

    /**
     * 初始化系统字典
     */
    public void initializeSysDictCache() {
        initializeSysDictDataCache();
        initializeSysDictTypeCache();
    }

    /**
     * 初始化系统字典类型表
     */
    public void initializeSysDictTypeCache() {
        sysDictTypeMapper.selectList().forEach(sysDictType ->
            HazelcastUtils.addCache(CacheNames.SYS_DICT_TYPE, sysDictType.getDictType(), sysDictType)
        );
    }

    /**
     * 初始化系统字典数据表
     */
    public void initializeSysDictDataCache() {
        sysDictTypeMapper.selectList().forEach(sysDictType -> {
            List<SysDictData> sysDictDataList = sysDictDataMapper.selectList(new LambdaQueryWrapper<SysDictData>()
                .eq(SysDictData::getDictType, sysDictType.getDictType())
                .orderByAsc(SysDictData::getDictSort));
            HazelcastUtils.addCache(CacheNames.SYS_DICT_DATA, sysDictType.getDictType(), sysDictDataList);
        });
    }

    /**
     * 初始化系统配置表
     */
    public void initializeSysConfigCache() {
        sysConfigMapper.selectList().forEach(sysConfig ->
            HazelcastUtils.addCache(CacheNames.SYS_CONFIG, sysConfig.getConfigKey(), sysConfig.getConfigValue())
        );
    }

    /**
     * 初始化报文模板表
     */
    public void initializePmMsgTemplate() {
        log.info("加载报文模板表-开始");
        pmMsgTemplateMapper.selectList().forEach(msgTpl -> {
            HazelcastUtils.addCache(CacheNames.PM_MSG_TEMPLATE, msgTpl.getMsgTemplateCode(), msgTpl);
        });
        log.info("加载报文模板表-结束");
    }

    /**
     * 唯一性模板验证
     */
    public void initializePmUniqueValidation() {
        log.info("加载唯一性校验模板-开始");
        List<PmUniqueElement> pmUniqueElements = pmUniqueElementMapper.selectList();
        pmUniqueValidationMapper.selectList().forEach(pmUniqueValidation -> {
            String tempId = pmUniqueValidation.getTempId();
            List<PmUniqueElement> collect = pmUniqueElements.stream()
                .filter(pmUniqueElement -> tempId.equals(pmUniqueElement.getTempId()))
                .collect(Collectors.toList());
            HazelcastUtils.addCache(CacheNames.PM_UNIQUE_VALIDATION, tempId, collect);
        });
        log.info("加载唯一性校验模板-结束");
    }

}
